﻿using System;
using System.Windows;
using System.Windows.Input;
using HeritageAcademy.Models.DataModels;

namespace HeritageAcademy.Library.Controls
{
    /// <summary>
    /// Interaction logic for BookViewerScrubber.xaml
    /// </summary>
    public partial class BookViewerSlider
    {
        #region Parameters
        bool isMouseDown;
        double _lastValueUsedForLocation = Double.NaN;
        CourseLocation _lastLocation;
        #endregion

        #region Ctor
        public BookViewerSlider()
        {
            InitializeComponent();
        }
        #endregion

        #region Protected Methods
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            isMouseDown = true;
            Mouse.Capture(this, CaptureMode.SubTree);

            var p = e.GetPosition(this);
            Value = p.X / ActualWidth;

            base.OnMouseDown(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (isMouseDown)
            {
                var p = e.GetPosition(this);
                Value = p.X / ActualWidth;
                ShowThumbnail();
            }

            base.OnMouseMove(e);
        }

        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            if (isMouseDown)
            {
                isMouseDown = false;
                ReleaseMouseCapture();
                HideThumbnail();
                Navigate();
            }

            base.OnMouseUp(e);
        }
        #endregion Protected Methods

        #region Private Methods
        private void HideThumbnail()
        {
            Thumbnail.IsOpen = false;
        }

        private void Navigate()
        {
            if (BookView != null)
                BookView.GotoPercentage(Value);
        }

        private void ShowThumbnail()
        {
            if (BookView == null) return;
            var location = Location;

            if (location == null) return;
            if (Thumbnail.IsOpen == false) Thumbnail.IsOpen = true;

            // Position
            var position = Math.Max(BookView.PercentageToPosition(Value), 1);
            PositionTextBlock.Text = position.ToString();

            // chapter title
            var ch = BookView.GetChapter(location.Chapter);
            ChapterNameTextBlock.Text = ch.Model.Title;

            // percentage
            PercentageTextBlock.Text = String.Format("{0:0.0}%", Value * 100);
        }

        private void UpdateIndicator()
        {
            Indicator.Width = Math.Max(5.0, Value * ActualWidth);
            Thumbnail.HorizontalOffset = Indicator.Width;
        }
        #endregion Private Methods

        #region Value
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(double), typeof(BookViewerSlider),
                new FrameworkPropertyMetadata(0.0,
                    new PropertyChangedCallback(OnValueChanged),
                    CoerceValueValue));

        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((BookViewerSlider)d).OnValueChanged(e);
        }

        protected virtual void OnValueChanged(DependencyPropertyChangedEventArgs e)
        {
            UpdateIndicator();
        }

        private static object CoerceValueValue(DependencyObject d, object value)
        {
            var v = (double)value;
            v = Math.Min(1.0, Math.Max(0.0, v));
            return v;
        }
        #endregion

        #region Properties
        private CourseLocation Location
        {
            get
            {
                if (Value != _lastValueUsedForLocation)
                {
                    _lastValueUsedForLocation = Value;
                    _lastLocation = BookView.PercentageToBookLocation(Value);
                }
                return _lastLocation;
            }
        }

        /// <summary>
        /// BookView Dependency Property
        /// </summary>
        public static readonly DependencyProperty BookViewProperty =
            DependencyProperty.Register("BookView", typeof(BookViewer), typeof(BookViewerSlider),
                new FrameworkPropertyMetadata(null,
                    new PropertyChangedCallback(OnBookViewChanged)));

        /// <summary>
        /// Gets or sets the BookView property.  This dependency property 
        /// indicates ....
        /// </summary>
        public BookViewer BookView
        {
            get { return (BookViewer)GetValue(BookViewProperty); }
            set { SetValue(BookViewProperty, value); }
        }

        /// <summary>
        /// Handles changes to the BookView property.
        /// </summary>
        private static void OnBookViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((BookViewerSlider)d).OnBookViewChanged(e);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the BookView property.
        /// </summary>
        protected virtual void OnBookViewChanged(DependencyPropertyChangedEventArgs e)
        {
            var old = e.OldValue as BookViewer;
            if (old != null)
            {
                old.LocationChanged -= b_LocationChanged;
                old.PaginationCompleted -= b_PaginationCompleted;
            }

            var b = e.NewValue as BookViewer;
            if (b != null)
            {
                b.LocationChanged += b_LocationChanged;
                b.PaginationCompleted += b_PaginationCompleted;
            }
        }

        void b_PaginationCompleted(object sender, RoutedEventArgs e)
        {
            UpdateValueFromBookLocation();
        }

        void b_LocationChanged(object sender, RoutedEventArgs e)
        {
            UpdateValueFromBookLocation();
        }

        private void UpdateValueFromBookLocation()
        {
            //if (BookView.IsPaginationValid)
            //{
            Value = BookView.Percentage;
            //}
        }
        #endregion
    }
}
